---
type: tutorial
title: Construye tu primer plantilla
i18nReady: true
description: |-
  Tutorial: Crea tu primer blog con Astro —
  Refactorización de elementos comunes en un diseño de página reutilizable
---
import Box from '~/components/tutorial/Box.astro';
import Checklist from '~/components/Checklist.astro';
import MultipleChoice from '~/components/tutorial/MultipleChoice.astro';
import Option from '~/components/tutorial/Option.astro';
import PreCheck from '~/components/tutorial/PreCheck.astro';
import { Steps } from '@astrojs/starlight/components';

<PreCheck>
  - Refactorizar elementos comunes en un diseño de página
  - Utilizar el elemento `<slot />` de Astro para colocar el contenido de la página dentro de una plantilla
  - Pasar valores específicos de la página como props a tu plantilla
</PreCheck>

Todavía tienes algunos componentes de Astro repetidamente renderizados en cada página. ¡Es hora de refactorizar para crear una plantilla de página compartido!

## Crea tu primer componente plantilla

<Steps>
1. Crea un nuevo archivo en la ubicación `src/layouts/BaseLayout.astro`. (Tendrás que crear primero una nueva carpeta `layouts`).

2. Copia el **contenido completo** de `index.astro` en tu nuevo archivo, `BaseLayout.astro`.

    ```astro title="src/layouts/BaseLayout.astro"
    ---
    import Header from '../components/Header.astro';
    import Footer from '../components/Footer.astro';
    import '../styles/global.css';
    const pageTitle = "Página de inicio";
    ---
    <html lang="es">
      <head>
        <meta charset="utf-8" />
        <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
        <meta name="viewport" content="width=device-width" />
        <meta name="generator" content={Astro.generator} />
        <title>{pageTitle}</title>
      </head>
      <body>
        <Header />
        <h1>{pageTitle}</h1>
        <Footer />
        <script>
          import "../scripts/menu.js";
        </script>
      </body>
    </html>
    ```
</Steps>

## Utiliza tu plantilla en una página

<Steps>
3. Sustituye el código en `src/pages/index.astro` por el siguiente:

    ```astro title="src/pages/index.astro"
    ---
    import BaseLayout from '../layouts/BaseLayout.astro';
    const pageTitle = "Página de inicio";
    ---
    <BaseLayout>
      <h2>Mi impresionante subtítulo del blog</h2>
    </BaseLayout>
    ```
 
4. Comprueba de nuevo la vista previa del navegador para ver qué ha cambiado (o, alerta de spoiler: ¡no ha cambiado!).
    
5. Añade un elemento `<slot />` a `src/layouts/BaseLayout.astro` justo encima del componente de pie de página y, a continuación, comprueba la vista previa del navegador de tu página de inicio y observa lo que realmente ha cambiado esta vez.

    ```astro title="src/layouts/BaseLayout.astro" ins={18}
    ---
    import Header from '../components/Header.astro';
    import Footer from '../components/Footer.astro';
    import '../styles/global.css';
    const pageTitle = "Página de inicio";
    ---
    <html lang="es">
      <head>
        <meta charset="utf-8" />
        <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
        <meta name="viewport" content="width=device-width" />
        <meta name="generator" content={Astro.generator} />
        <title>{pageTitle}</title>
      </head>
      <body>
        <Header />
        <h1>{pageTitle}</h1>
        <slot />
        <Footer />
        <script>
          import "../scripts/menu.js";
        </script>
      </body>
    </html>
    ```
</Steps>

 La etiqueta `<slot />` permite inyectar (o "introducir") **contenido hijo** escrito entre las etiquetas de apertura y cierre `<Component></Component>` en cualquier archivo `Component.astro`.

## Pasa valores específicos de la página como props

<Steps>
6. Pasa el título de la página a tu componente plantilla desde `index.astro` utilizando un atributo de componente: 

    ```astro title="src/pages/index.astro" 'pageTitle={pageTitle}'
    ---
    import BaseLayout from '../layouts/BaseLayout.astro';
    const pageTitle = "Página de inicio";
    ---
    <BaseLayout pageTitle={pageTitle}>
      <h2>Mi impresionante subtítulo del blog</h2>
    </BaseLayout>
    ```

7. Cambia el script de tu componente plantilla `BaseLayout.astro` para recibir un título de página a través de `Astro.props` en lugar de definirlo como una constante.

    ```astro title="src/layouts/BaseLayout.astro" del={5} ins={6}
    ---
    import Header from '../components/Header.astro';
    import Footer from '../components/Footer.astro';
    import '../styles/global.css';
    const pageTitle = "Página de inicio";
    const { pageTitle } = Astro.props;
    ---
    ```

8. Comprueba la vista previa de tu navegador para verificar que el título de tu página no ha cambiado. Tiene el mismo valor, pero ahora se muestra dinámicamente. Y ahora, en cada página individual puedes especificar tu propio título en la plantilla.
</Steps>

<Box icon="puzzle-piece">

## Pruébalo tu mismo - Utiliza tu plantilla en todas partes

**Refactoriza** tus otras páginas (`blog.astro` y `about.astro`) para que utilicen tu nuevo componente `<BaseLayout>` para renderizar los elementos comunes de la página.

No olvides:

- Pasar un título de página como props a través de un atributo de componente.

- Dejar que la plantilla se encargue de la representación HTML de los elementos comunes.

- Eliminar cualquier cosa de cada página donde esa página ya no es responsable de la representación, ya que está siendo manejado por la plantilla, incluyendo: 

  - Elementos HTML
  - Componentes y tus importaciones 
  - Reglas CSS en una etiqueta `<style>` (por ejemplo, `<h1>` en tu página 'Acerca de').
  - Etiquetas `<script>`.
</Box>



<Box icon="question-mark">

### Pon a prueba tus conocimientos

1. Un componente de Astro (archivo `.astro`) puede funcionar como una:

    <MultipleChoice>
      <Option>página</Option>
      <Option>componente UI</Option>
      <Option>plantilla</Option>
      <Option isCorrect>todo lo anterior, ¡porque los componentes Astro son muy funcionales! 🏗️</Option>
    </MultipleChoice>

2. Para mostrar un título de página en la página, puedes:

    <MultipleChoice>
      <Option>
        utilizar un elemento HTML estándar en la página con texto estático (por ejemplo `<h1>Página de inicio</h1>`)
      </Option>
      <Option>
        utilizar un elemento HTML estándar en la página que haga referencia a una variable definida en el script frontmatter del componente (por ejemplo, `<h1>{pageTitle}</h1>`)
      </Option>
      <Option>
        utilizar un componente plantilla en la página, pasando el título como atributo del componente (por ejemplo, `<BaseLayout title="Página de inicio" />` o `<BaseLayout title={pageTitle} />`)
      </Option>
      <Option isCorrect>
        todo lo anterior, porque Astro te permite utilizar HTML plano o sobrecargarlo con algunos scripts y componentes. 💪
      </Option>
    </MultipleChoice>

3. La información puede pasar de un componente a otro mediante:

    <MultipleChoice>
      <Option>
        importar un componente de UI y representarlo en la plantilla de otro componente
      </Option>
      <Option>
        pasar props a un componente donde se renderiza mediante un atributo del componente
      </Option>
      <Option>
        enviar contenido HTML para que se muestre dentro de otro componente utilizando un marcador de posición `<slot />`.
      </Option>
      <Option isCorrect>
        todo lo anterior, porque Astro se creó para aprovechar las ventajas del diseño basado en componentes. 🧩
      </Option>
    </MultipleChoice>

</Box>

<Box icon="check-list">

## Checklist

<Checklist>
- [ ] Puedo crear un componente plantilla de Astro con `<slot />`.
- [ ] Puedo enviar propiedades específicas de la página a una plantilla.
</Checklist>
</Box>

### Recursos

- [Componentes de plantilla en Astro](/es/basics/layouts/)

- [`<slot />` de Astro](/es/basics/astro-components/#slots)
